package core.reports;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;


public class HTMLBuilder implements IBuilder 
{
	/** Keeps track of whether or not this 
	 * document has been completed, as defined
	 * by the 'finish()' method.
	 */
	private boolean finished = false;
	
	/** Stores the name of the file that we are outputting to. */
	private String filename;
        private FileWriter fstream;
        private BufferedWriter out;
        
        /** The number of cloumns in the current table. */
        private int numCols;
        /** How many cells have been inserted into current table */
        private int numInserted;
        /** Is a table open */
        private boolean tableOpen;
        /** Is a list open */
        private boolean listOpen;
	
	/**
	 * This creates an HTMLBuilder object that
	 * will output an HTML file to the parameter
	 * filename.  When this object is created
	 * it will create the file 'filename' and
	 * keep it open until 'finish()' is called.
	 * 
	 * @param filename The name of the output file
	 * 		that will contain the output of this 
	 * 		object.
	 */
	public HTMLBuilder(String filename)
	{
            numCols = 0;
            this.filename = filename;
            try {

                fstream = new FileWriter(filename);

            } catch (IOException ex) {
                Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }
                out = new BufferedWriter(fstream);
                
                try 
                {
					out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"+
							"\n\n<html>\n<head>\n     <title></title>\n</head>\n<body>\n");
				} 
                catch (IOException e) 
                {
					e.printStackTrace();
				}
                
                tableOpen = false;
                listOpen = false;
	}
	
	/**
	 * Returns the name of the file that this object
	 * is outputting the data to.
	 * 
	 * @return A String that contains the filename of
	 * 		where the data is getting saved.
	 */
	public String getFileName()
	{
		return filename;
	}
	
	@Override
	public void addTitle(String title) 
	{
		if (finished) return;
		
            try {
                
                out.write("<h1>"+title+"</h1>\n");
                
            } catch (IOException ex) {
                Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }
	}

	@Override
	public void addParagraph(String text) 
	{
		if (finished) return;
		
            try {
                    
                out.write("<p>" + text + "</p>");
                
            } catch (IOException ex) {
                Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }

	}

	@Override
	public void addTable(int numCols)
	{
		if (finished) return;
		
		if (tableOpen == true) return;
		
        this.numCols = numCols;
        this.numInserted = 0;
		
        try 
        {
        	out.write("<table border=\"1\">\n     <tr>\n");
        	this.tableOpen = true;
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }
	}

	@Override
	public void addColumnHeader(String header) 
	{
		if (finished) return;
		
		if (tableOpen == false) return;
		
        try 
        {
        	
        	this.numInserted++;
            
            if (this.numInserted > this.numCols)
            {	
            	this.numInserted -= this.numCols;
            	out.write("     </tr>\n     <tr>\n");
            }
                
            out.write("          <th>" + header +"</th>\n");
            
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }

	}

	@Override
	public void addCell(String data) 
	{
		if (finished) return;
		
		if (tableOpen == false) return;
		
            try {
                  
            	this.numInserted++;
                
                if (this.numInserted > this.numCols)
                {	
                	this.numInserted -= this.numCols;
                	out.write("     </tr>\n     <tr>\n");
                }
            	
                out.write("          <td>" + data +"</td>\n");
                
            } catch (IOException ex) {
                Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }

	}

	@Override
	public void closeCurrentTable()
	{
		if (finished) return;
		
		if (tableOpen == false) return;
		
		try 
		{
			for (int i = 0; i < (this.numCols - numInserted); i++)
			{
				out.write("          <td> </td>\n");
			}
            out.write("     </tr>\n</table>\n");
            this.tableOpen = false;
            
        } 
		catch (IOException ex)
		{
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }

	}

	@Override
	public void addList() 
	{
		if (finished) return;
		
		if (listOpen) return;
		
        try 
        {
                
            out.write("<ul>\n");
            listOpen = true;
            
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }

	}

	@Override
	public void addListItem(String item)
	{
		if (finished) return;
		
		if (listOpen == false) return;
		
        try 
        {
                
            out.write("     <li>" + item + "</li>\n");
            
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }

	}

	@Override
	public void closeCurrentList() 
	{
		if (finished) return;
		
		if (listOpen == false) return;
		
        try 
        {
                
            out.write("</ul>\n");
            listOpen = false;
            
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }

	}

	@Override
	public void finish() 
	{
		if (finished) return;
		
		if (tableOpen) closeCurrentTable();
		if (listOpen) closeCurrentList();
		
            try {
            	
            	out.write("</body>\n</html>\n");
            	
            	out.close();
            	finished = true;
                
            } catch (IOException ex) {
                Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }
	}

	@Override
	public void addBlankLine() 
	{
		if (finished) return;
		
		try {
            
            out.write("<br>\n");
            
        } catch (IOException ex) {
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }
	}

	@Override
	public void addSubTitle(String subTitle) 
	{
		if (finished) return;
		
		try 
		{
            out.write("<h3>"+subTitle+"</h3>\n");    
        } 
		catch (IOException ex) 
		{
            Logger.getLogger(HTMLBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }
	}

}
